package homework.mission2;

import java.util.Scanner;

public class WuZiQi {
    /**
     * 定义棋盘的行数和列数
     */
    private static int ROW = 16;
    private static int COLUMN = 16;

    // 棋盘
    private static String[][] CHESS_BOARD;

    static {
        createChessBoard();
    }

    /**
     * 轮换提示 true: 黑子下，false: 白子下
     */
    private static boolean TURN = true;

    /**
     * 表示其中一方是否获胜
     */
    private static boolean SOMEONE_WIN = false;

    /**
     * 表示两个下棋所占的格子数
     */
    private static int STEP = 0;


    public static void main(String[] args) {
        // 获取用户输入对象
        Scanner sc = new Scanner(System.in);

        /**
         * 循环判断下棋（如果有一方获胜或者棋盘沾满，则退出）
         */
        while (!SOMEONE_WIN && STEP < 15 * 15) {
            /**
             * 判断此刻是该哪一方下棋了
             */
            if(TURN) {
                // 黑棋下
                TURN = playChess(true, CHESS_BOARD, sc);
            } else {
                // 白棋下
                TURN = playChess(false, CHESS_BOARD, sc);
            }
        }
    }

    /**
     * 下棋
     */
    private static boolean playChess(boolean turn, String[][] board, Scanner sc) {
        justifyTurn(turn);

        while (true) {
            System.out.println("请输入行数和列数, 格式 => 行数,列数");
            String[] points = sc.next().split(",");

            // 判断用户输入的行数和列数是否齐全
            if(points.length < 2) {
                System.out.println("行数列数缺失");
                justifyTurn(turn);
            } else {
                // 获取用户输入的要下棋的行数和列数
                int row = Integer.parseInt(points[0]);
                int column = Integer.parseInt(points[1]);

                // 判断该位置是否超出棋盘范围
                if((row < 1) || (row > 15) || (column < 1) || (column > 15)) {
                    System.out.println("该位置超出棋盘范围");
                    justifyTurn(turn);
                } else {
                    // 判断该位置是否已有棋子
                    if(!(board[row][column]).equals("+")) {
                        System.out.println("该位置已有棋子");
                        justifyTurn(turn);
                    } else {
                        // 下棋,并判断是否连成 5 子
                        if(turn) {
                            board[row][column] = "●";
                        } else {
                            board[row][column] = "○";
                        }

                        // 步数增加
                        STEP ++;

                        // 判断是否获胜
                        if(justifyWinColumn(column, row) || justifyWinRow(column,row) || justifyWinLeftRight(column, row) || justifyWinRightLeft(column, row)) {
                            SOMEONE_WIN = true;
                        }

                        // 打印棋盘
                        printChessBoard();

                        return !turn;
                    }
                }
            }
        }
    }

    /**
     * 判断当前落子的点所在的由右上到左下的这条斜线上 "/"
     * @param column
     * @param row
     * @return
     */
    private static boolean justifyWinRightLeft(int column, int row) {
        /**
         * 判断当前正在下的谁黑子还是白子
         */
        String temp = "";
        if(TURN) {
            temp = "●";
        } else {
            temp = "○";
        }

        // 创建统计变量，统计连线棋子的个数
        int sum = 0;

        for (int i = 4; i >= -4 ; i--) {
            if((row - i) >= 1 &&(row - i) < 16  && (column + i) < 16 && (column + i) >= 1) {
                if(CHESS_BOARD[row - i][column + i].equals(temp)) {
                    sum ++;
                } else {
                    sum = 0;
                }
            }
            if(sum == 5) {
                System.out.println(TURN ? "黑子赢了" : "白子赢了");
                return true;
            }
        }

        return false;
    }

    /**
     * 判断当前落子所在的由左上到右下的这条斜线上 "\"
     * @param column
     * @param row
     * @return
     */
    private static boolean justifyWinLeftRight(int column, int row) {
        /**
         * 判断当前正在下的谁黑子还是白子
         */
        String temp = "";
        if(TURN) {
            temp = "●";
        } else {
            temp = "○";
        }

        // 创建统计变量，统计连线棋子的个数
        int sum = 0;
        for (int i = -4; i <= 4; i++) {
            if((row + i) >= 1 && (row + i) < 16 && (column + i) >= 1 && (column + i) < 16) {
                if((CHESS_BOARD[row + i][column + i]).equals(temp)) {
                    sum ++;
                } else {
                    sum = 0;
                }
            }
            if(sum == 5) {
                System.out.println(TURN ? "黑子赢了" : "白子赢了");
                return true;
            }
        }

        return false;
    }

    /**
     * 判断当前列是否满足5子连线
     * @param column
     * @param row
     * @return
     */
    private static boolean justifyWinRow(int column, int row) {
        /**
         * 判断当前正在下的谁黑子还是白子
         */
        String temp = "";
        if(TURN) {
            temp = "●";
        } else {
            temp = "○";
        }

        /**
         * 判断当前列是否5子连线，所以是以当前落子的点为中点，往上数4个，往下数4个
         * 在这个范围中查看是否满足5子连线
         */
        int minRow = row - 4;
        int maxRow = row + 4;

        /**
         * 如果往数4个的值比上边界还要小，那就以上边界为 查找5子连线的范围的上边界
         * 因为最上边是棋盘的刻度，所以这是1
         * 往下如果超过棋盘的下边界，那这个范围的最大值就是下边界
         */
        if(minRow < 1) minRow = 1;
        if(maxRow > 15) maxRow = 15;

        // 声明统计变量
        int sum = 0;
        for (int i = minRow; i < maxRow; i++) {
            if(CHESS_BOARD[i][column].equals(temp)) {
                sum ++;
                if(sum == 5) {
                    System.out.println(TURN ? "黑子赢了" : "白子赢了");
                    return true;
                }
            } else {
                sum = 0;
            }
        }

        return false;
    }

    /**
     * 判断当前行是否满足5子连线
     * @param column
     * @param row
     * @return
     */
    private static boolean justifyWinColumn(int column, int row) {
        /**
         * 判断当前正在下的谁黑子还是白子
         */
        String temp = "";
        if(TURN) {
            temp = "●";
        } else {
            temp = "○";
        }

        /**
         * 判断当前行是否5子连线，所以是以当前落子的点为中点，往左数4个，和往右数4个
         * 在这个范围中查看是否满足5子连线
         */
        int minColumn = column - 4;
        int maxColumn = column + 4;

        /**
         * 如果往左数4个的值比左边界还要小，那就以左边界为查找 5 子连线的范围的左边界
         * 因为最左边是棋盘的刻度，所以这里是1
         * 往右如果超过棋盘的右边界，那这个范围的最大值就是右边界
         */
        if(minColumn < 1) minColumn = 1;
        if(maxColumn > 15) maxColumn = 15;

        // 创建统计变量
        int sum = 0;
        for (int i = minColumn; i < maxColumn; i++) {
            if(CHESS_BOARD[row][i].equals(temp)) {
                sum ++;
                if(sum == 5) {
                    System.out.println(TURN ? "黑子赢了" : "白子赢了");
                    return true;
                }
            } else {
                sum = 0;
            }
        }

        return false;
    }

    /**
     * 绘制棋盘
     */
    private static void createChessBoard() {
        String[][] chessBoard = new String[WuZiQi.ROW][WuZiQi.COLUMN];
        String[] strArr = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};

        //棋盘的第一行
        for (int i = 0; i < chessBoard[0].length; i++) {
            chessBoard[0][i] = strArr[i];
        }

        //棋盘的第一列
        for (int i = 0; i < chessBoard.length; i++) {
            chessBoard[i][0] = strArr[i];
        }

        //棋盘的其他行和列
        for (int i = 1; i < chessBoard.length; i++) {
            for (int j = 1; j < chessBoard[i].length; j++) {
                chessBoard[i][j] = "+";
            }
        }

        WuZiQi.CHESS_BOARD = chessBoard;
    }

    /**
     * 打印棋盘
     */
    private static void printChessBoard() {
        for (int i = 0; i < CHESS_BOARD.length; i++) {
            for (int j = 0; j < CHESS_BOARD[i].length; j++) {
                System.out.print(CHESS_BOARD[i][j] + " ");
            }
            System.out.println();
        }
    }

    /**
     * 提示该谁下棋了
     */
    private static void justifyTurn(boolean flag) {
        if(flag) {
            System.out.println("黑子下");
        } else {
            System.out.println("白子下");
        }
    }
}
